package geppetto.cat.programs;

import geppetto.cat.alignments.Alignment;
import geppetto.cat.alignments.AlignmentStats;
import geppetto.cat.alignments.AlignmentSymetrization;
import geppetto.cat.alignments.AlignmentsSet;
import geppetto.cat.alignments.output.AlignerOutput;
import geppetto.cat.corpus.BilingualCorpus;
import geppetto.cat.models.AbstractModel;
import gnu.trove.TIntIntHashMap;
import gnu.trove.TIntObjectHashMap;

import java.io.IOException;



public class ProducedPhrasesStats {
	
	
	static double[] HANSARDS_M4P_F = {0.8439};
	static double[] HANSARDS_M4R_F = {0.9433};
	static double[] HANSARDS_M4P_B={0.8489};
	static double[] HANSARDS_M4R_B={0.932};
	static double[] EPPS_M4P_F={0.8427};
	static double[] EPPS_M4R_F={0.7511};
	static double[] EPPS_M4P_B={0.8775};
	static double[] EPPS_M4R_B={0.7496};
	static double[] EN_PT_M4P_F={0.7979};
	static double[] EN_PT_M4R_F={0.8532};
	static double[] EN_PT_M4P_B={0.8391};
	static double[] EN_PT_M4R_B={0.8745};
	static double[] PT_ES_M4P_F={0.8795};
	static double[] PT_ES_M4R_F={0.9367};
	static double[] PT_ES_M4P_B={0.8456};
	static double[] PT_ES_M4R_B={0.9098};
	static double[] PT_FR_M4P_F={0.8501};
	static double[] PT_FR_M4R_F={0.8201};
	static double[] PT_FR_M4P_B={0.8452};
	static double[] PT_FR_M4R_B={0.7713};
	static double[] ES_FR_M4P_F={0.8525};
	static double[] ES_FR_M4R_F={0.7841};
	static double[] ES_FR_M4P_B={0.8837};
	static double[] ES_FR_M4R_B={0.7841};

	
	public static void main(String[] args) throws IOException {
		String corpusDescription = args[0];
		int size = Integer.parseInt(args[1]);
		int maxSentenceSize = Integer.parseInt(args[2]);
		
		System.out.println("Corpus " + corpusDescription);
		System.out.println("Size " + size);
		System.out.println("Max Sent length " + maxSentenceSize);
		
		BilingualCorpus forwardCorpus = BilingualCorpus.getCorpusFromFileDescription(corpusDescription, size,maxSentenceSize);
		BilingualCorpus backwardCorpus = forwardCorpus.reverse();	
	
		String forwardModelDir = args[3];
		String backwardModelDir = args[4];
		String modelName1 = args[5];
		double epsilon1 = Double.parseDouble(args[6]);
		double slack1 = Double.parseDouble(args[7]);
		int maxStep1 = Integer.parseInt(args[8]);
		int maxProjecIter1 = Integer.parseInt(args[9]);
		boolean allPoints = Boolean.parseBoolean(args[10]);
		boolean onlySure = Boolean.parseBoolean(args[11]);

		System.out.println("Model1 ");
		System.out.println("Forward Model Dir " + forwardModelDir);
		System.out.println("Backward Model Dir " + backwardModelDir);
		System.out.println("Model Name " + modelName1);
		System.out.println("Epsilon " + epsilon1);
		System.out.println("Slack " + slack1);
		System.out.println("Max Step " + maxStep1);
		System.out.println("Max Project Iterations " + maxProjecIter1);
		
		AbstractModel[] models= GenericMethods.initializeModelsFullDir(forwardCorpus, backwardCorpus, modelName1, 
				forwardModelDir,backwardModelDir, 
				epsilon1, slack1, maxStep1, maxProjecIter1);
	
		
		
		
		for(int i = 0; i < forwardCorpus.getGold().size(); i++){
			Alignment a = forwardCorpus.getGold().get(i);
			if(a._foreignLen < 8 && a._sourceLen < 8){
				AlignerOutput.output(a, System.out);
				TIntObjectHashMap<TIntIntHashMap> phrases = new TIntObjectHashMap<TIntIntHashMap>();
				AlignmentStats.numberOfPhrases(a, phrases, allPoints, onlySure);
				AlignmentStats.printPhrases(phrases, allPoints, onlySure);

			}
		}
				
		System.out.println("Number of phrases on gold");
		AlignmentStats.printPhrases(forwardCorpus.getGold(), allPoints, onlySure);
		
		
		double[] forwardR = null;
		double[] backwardR = null;
		
		if(forwardCorpus.getName().equalsIgnoreCase("hansards")){
			forwardR = HANSARDS_M4R_F;
			backwardR = HANSARDS_M4R_B;
		}else if(forwardCorpus.getName().equalsIgnoreCase("euro-en-es")){
			forwardR = EPPS_M4R_F;
			backwardR = EPPS_M4R_B;
		}else if(forwardCorpus.getName().equalsIgnoreCase("en-pt")){
			forwardR = EN_PT_M4R_F;
			backwardR = EN_PT_M4R_B;
		}else if(forwardCorpus.getName().equalsIgnoreCase("pt-es")){
			forwardR = PT_ES_M4R_F;
			backwardR = PT_ES_M4R_B;
		}else if(forwardCorpus.getName().equalsIgnoreCase("pt-fr")){
			forwardR = PT_FR_M4R_F;
			backwardR = PT_FR_M4R_B;
		}else if(forwardCorpus.getName().equalsIgnoreCase("es-fr")){
			forwardR = ES_FR_M4R_F;
			backwardR = ES_FR_M4R_B;
		}else{
			System.out.println("Don't have M4 Values... Exiting");
			System.exit(-1);
		}
		
		//For predicted alignments are points are marked as sure
		
		//AlignmentsSet alForward = models[0].viterbiAlignments(BilingualCorpus.TEST_CORPUS);
		float forwardThresh =
			models[0].tuneTreshholdPrecisionRecallFixOtherValue(BilingualCorpus.TEST_CORPUS, true, forwardR[0], 0.0005, true);
		float backwardThresh =
			models[1].tuneTreshholdPrecisionRecallFixOtherValue(BilingualCorpus.TEST_CORPUS, true, backwardR[0], 0.0005, true);
		System.out.println("Forward");
		AlignmentsSet alForward = models[0].posteriorAlignments(BilingualCorpus.TEST_CORPUS,
				forwardThresh,false,true);
		AlignmentStats.printPhrases(alForward, allPoints, onlySure);
		
		
		System.out.println("Backward");
		AlignmentsSet alBackward = models[1].posteriorAlignments(BilingualCorpus.TEST_CORPUS,
				backwardThresh,false,true);
			//models[1].viterbiAlignments(BilingualCorpus.TEST_CORPUS);
		AlignmentStats.printPhrases(alBackward, allPoints, onlySure);
		
		System.out.println("symmetry");
		AlignmentsSet intersection = AlignmentSymetrization.intersect(alForward, alBackward);
		AlignmentsSet union = AlignmentSymetrization.union(alForward, alBackward);
		System.out.println(" intersection over union " + intersection.numberOfAlignedPoints()*1.0/union.numberOfAlignedPoints());
		if(!modelName1.equalsIgnoreCase("regularHMM")){
			System.out.println("doing projection");
			alForward = models[0].posteriorAlignments(BilingualCorpus.TEST_CORPUS,
					forwardThresh,true,true);
				//models[0].viterbiAlignments(BilingualCorpus.TEST_CORPUS,true);
			alBackward = models[1].posteriorAlignments(BilingualCorpus.TEST_CORPUS,
					backwardThresh,true,true);
				//models[1].viterbiAlignments(BilingualCorpus.TEST_CORPUS,true);
			System.out.println("Forward");
			AlignmentStats.printPhrases(alForward, allPoints, onlySure);
			System.out.println("Backward");
			AlignmentStats.printPhrases(alBackward, allPoints, onlySure);
			System.out.println("symmetry");
			intersection = AlignmentSymetrization.intersect(alForward, alBackward);
			union = AlignmentSymetrization.union(alForward, alBackward);
			System.out.println(" intersection over union " + intersection.numberOfAlignedPoints()*1.0/union.numberOfAlignedPoints());
		}
		
	}
}
